/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-6-5 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-6-5		Created.
 ****************************************************************************
 **/
package com.me.client;

import java.awt.Color;
import java.awt.SystemColor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.swing.JOptionPane;
import javax.swing.ListModel;
import javax.swing.UIManager;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import com.me.client.JTalkParser.ClientSettings;

/**
 * 
 * <br/>
 * 下午8:02:06 2012-6-5
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class JTalkClient implements Comparator {

	public static final int STATE_OFFLINE = 0;
	public static final int STATE_LOGGING = 1;
	public static final int STATE_CONNECTED = 2;
	public static final int STATE_ACCOUNT_CREATION = 3;
	public String guiTextColor = null;
	public int state = STATE_LOGGING;
	public String userStatus = null;

	public String serverName = null;
	public boolean isConnected = false;

	/** 客户端Socket */
	private Socket socket = null;
	/** 输出流 */
	private PrintWriter out = null;
	/** 输入流 */
	private BufferedReader in = null;

	/** 客户端用户名 */
	public String userName = "";
	/** 客户端密码 */
	public String password = "";
	/** 服务器地址 */
	private String serverAddress = "localhost";
	/** 服务器端口 */
	public int serverPort = 4443;
	/* 服务器端地址 */
	private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress("localhost", 4443);
	/* 缓冲区大小 */
	public static int BLOCK = 4096;
	/* 接受数据缓冲区 */
	private ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK);
	/* 发送数据缓冲区 */
	private ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK);
	private Selector selector = null;
	private Set<SelectionKey> keys = null;
	private Iterator<SelectionKey> iterator = null;
	private SelectionKey key = null;
	private SocketChannel socketChannel = null;
	private int count = 0;
	private String receiveText = null;
//	private String sendText = null;
	private JTalkClientThread clientThread = null;
	public JTalkClientProtocal myProtocal = null;

	/** JList Model. */
	public MemberList memberList = null;
	public List<MemberData> allMembers = null;
	private List<JTalkClientCommandInterface> commands = null;
	private String lastCommandResponse = null;
	public boolean useSSL = false;
	public boolean savePassword = false;
	public String defaultBrowser;
	public String defaultMailer;
	public int newMailNotificationType = 2;
	public String guiPlaf;
	public String guiBgColor;
	public String pluginDir;
	private String configFile;
	private String pluginShortcuts;
	private JTalkClientFront myFrontend = null;
	private JTalkClientThread thread = null;

	public JTalkClient() {
		this.configFile = System.getProperty("user.home") + File.separator + ".jtalk.conf";
		this.pluginDir = System.getProperty("user.name") + File.separator;
		this.isConnected = false;
		memberList = new MemberList();
		allMembers = new ArrayList<MemberData>();
		guiTextColor = JTalkClient.getColorAsString(SystemColor.textText);
		if (!loadConfigFile()) {
			JOptionPane.showMessageDialog(null,
					"You are using JTalker for the first time.\nPlease check the configuration!",
					"Config file not found (" + this.configFile + ") !", JOptionPane.INFORMATION_MESSAGE);
			this.serverPort = 4443;
			this.serverName = "localhost";
			this.useSSL = false;
			this.userName = System.getProperty("user.name");
			this.userStatus = "normal";
			this.password = "";
			this.savePassword = false;
			this.defaultBrowser = "chrome";
			this.defaultMailer = "foxmail";
			this.guiPlaf = UIManager.getLookAndFeel().getClass().getName();
			this.guiTextColor = JTalkClient.getColorAsString(SystemColor.textText);
			this.guiBgColor = JTalkClient.getColorAsString(SystemColor.controlHighlight);
			this.newMailNotificationType = 2;
			this.pluginDir = System.getProperty("user.home") + File.separator;
			this.pluginShortcuts = "";
		}
		commands = new ArrayList<JTalkClientCommandInterface>();
		this.myProtocal = new JTalkClientProtocal(this);
	}

	/**
	 * 加载配置文件.
	 * 
	 * @return
	 */
	private boolean loadConfigFile() {
		// TODO Auto-generated method stub
		File myConfig = new File(this.configFile);
		JTalkParser parser = new JTalkParser();
		if (parser.parsing(myConfig)) {
			ClientSettings settings = parser.getClientSettings();
			this.serverName = settings.serverIP;
			this.serverPort = Integer.parseInt(settings.serverPort);
			this.useSSL = Boolean.valueOf(settings.serverSSL).booleanValue();
			this.defaultBrowser = settings.appsBrowser;
			this.defaultMailer = settings.appsMail;
			this.userName = settings.accountName;
			this.password = settings.accountPasswd;
			if (this.password == null) {
				this.savePassword = false;
			}
			this.guiPlaf = settings.lookPlaf;
			if (this.guiPlaf == null) {
				this.guiPlaf = UIManager.getLookAndFeel().getClass().getName();
			}
			this.guiTextColor = settings.lookTextcolor;
			if (this.guiTextColor == null) {
				this.guiTextColor = JTalkClient.getColorAsString(SystemColor.textText);
			}
			this.guiBgColor = settings.lookBgcolor;
			if (this.guiBgColor == null) {
				this.guiBgColor = JTalkClient.getColorAsString(SystemColor.controlHighlight);
			}
			try {
				this.newMailNotificationType = Integer.parseInt(settings.notifUserlist);
			} catch (Exception e) {
				this.newMailNotificationType = 2;
			}
			this.pluginDir = settings.pluginsDir;
			this.pluginShortcuts = settings.pluginsShortcuts;
		} else {
			return false;
		}
		return true;
	}

	/**
	 * 获取颜色值，格式如"#RRGGBB".
	 * 
	 * @param texttext
	 * @return
	 */
	public static String getColorAsString(Color color) {
		if (color != null) {
			String retVal = "#";
			String hexNum = "";
			hexNum = Integer.toHexString(color.getRed());
			if (hexNum.length() == 1)
				hexNum = ("0" + hexNum);
			retVal += hexNum;
			hexNum = Integer.toHexString(color.getGreen());
			if (hexNum.length() == 1)
				hexNum = ("0" + hexNum);
			retVal += hexNum;
			hexNum = Integer.toHexString(color.getBlue());
			if (hexNum.length() == 1)
				hexNum = ("0" + hexNum);
			retVal += hexNum;
			return retVal;
		}
		return null;
	}

	public boolean connect() {
		boolean connectedSuccessfully = false;
		try {
			// this.socket = new Socket(serverAddress, serverPort);
			// this.out = new PrintWriter(socket.getOutputStream(), true);
			// this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			socketChannel = SocketChannel.open();
			socketChannel.configureBlocking(false);
			selector = Selector.open();
			socketChannel.register(selector, SelectionKey.OP_CONNECT);
			socketChannel.connect(SERVER_ADDRESS);
			
			while(this.state != JTalkClient.STATE_CONNECTED){
			int c = selector.select();
			System.out.println("count1:" + c);
			keys = selector.selectedKeys();
//			System.out.println("count1:" + keys.size());
			iterator = keys.iterator();
			while (iterator.hasNext()) {
				key = iterator.next();
				iterator.remove();
				socketChannel = (SocketChannel) key.channel();
				if (key.isConnectable()) {
					if (socketChannel.isConnectionPending()) {
						socketChannel.finishConnect();
						// sendbuffer.clear();
						// sendbuffer.put("Hello,Server".getBytes());
						// sendbuffer.flip();
						// client.write(sendbuffer);
						System.out.println("connect");
						connectedSuccessfully = true;
						socketChannel.register(selector, SelectionKey.OP_READ);
					}
//					client.register(selector, SelectionKey.OP_WRITE);
					// System.out.println("客户端等待连接:OP_ACCEPT");
				} else if (key.isReadable()) {
				 receiveBuffer.clear();
				 count = socketChannel.read(receiveBuffer);
				 if(count > 0){
					 receiveText = new String(receiveBuffer.array(), 0, count);
					 this.myProtocal.processServerPackage(receiveText);
	//				 System.out.println("客户端接受服务器端数据--:" + receiveText);
					 socketChannel.register(selector, SelectionKey.OP_READ);
				 }
				 }
//				 else if (key.isWritable()) {
				// client = (SocketChannel)key.channel();
				// sendbuffer.clear();
				// sendText = "****";
				// sendbuffer.put(sendText.getBytes());
				// sendbuffer.flip();
				// client.write(sendbuffer);
				// client.register(selector, SelectionKey.OP_READ);
				// }
			}
			 }
			// this.out.println("----Connect Server---");
			// System.out.println("---------Client Message---------" + msgFromServer);
//			for(int i = 0; i < 5; i++){
//				c = selector.select();
//				System.out.println("count2:" + c);
//			}
			thread = new JTalkClientThread(this);
			thread.start();
			thread.setChannelReadable();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// String fromServer = null; // reply from server.
		// try {
		// String messageFromServer = this.in.readLine();
		// System.out.println("--[recv:]" + messageFromServer);
		// if (this.saveServerReply(messageFromServer)) {
		// this.socket.setSoTimeout(0);
		// this.clientThread = new JTalkClientThread(this, this.in);
		// this.clientThread.start();
		// connectedSuccessfully = true;
		// // this.loginServer();
		// }
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
		this.isConnected = true;
		return connectedSuccessfully;
	}

	public Selector getSelector() {
		return selector;
	}

	public ByteBuffer getReceiveBuffer() {
		return receiveBuffer;
	}

	/** Logins user */
	public boolean loginOnServer() {
		this.state = STATE_LOGGING;
		System.out.println(">>> Login on server...");
		return this.myProtocal.sendUserStatus(true);
	}

	public JTalkClientProtocal getMyProtocal() {
		return myProtocal;
	}

	/**
	 * 创建新的用户.
	 * 
	 * @param userName
	 *            用户名
	 * @param password
	 *            密码
	 */
	public boolean createNewAccount(String userName, String password) {
		// TODO Auto-generated method stub
		boolean retVal = false;
		if (this.isConnected) {
			this.closeConnection();
		}
		if (this.connect()) {
			System.out.println(">>> Try to create a new account...");
			this.state = STATE_ACCOUNT_CREATION;
			retVal = this.myProtocal.sendNewAccount(userName, password);
		}

		return retVal;
	}

	/**
	 * 登录服务器.
	 */
	private boolean loginServer() {
		// TODO Auto-generated method stub
		boolean loginSuccessfully = false;
		this.state = STATE_LOGGING;
		String loginMessage = "<JTALKER><MEMBER name=\"";
		loginMessage += this.userName + "\" status=\"" + this.userStatus + "\" ";
		loginMessage += "passwd=\"" + this.password + "\" /></JTALKER>";
		System.out.println("--[Send:]" + loginMessage);
//		this.out.println(loginMessage);
		this.sendToServer(loginMessage);
		loginSuccessfully = true;
		return loginSuccessfully;
	}

	@SuppressWarnings("unchecked")
	public boolean addMember(String name, String status, String userType, String message, String ip, String subject,
			String type) {
		// TODO Auto-generated method stub
		// 人员已存在于登录列表中则直接返回true;
		for (int i = 0; i < this.allMembers.size(); i++) {
			MemberData data = this.allMembers.get(i);
			// System.out.println("--[MemberData:]--" + data.short_name);
			if (data.short_name.equals(name)) {
				if (message != null) {
					data.addMessage(message, subject, type);
				}
				if (status != null) {
					data.status = status;
				}
				return true;
			}
		}
		// 人员不存在于登录列表中新增进去;
		MemberData newMember = new MemberData(name, ip, status, userType);
		this.allMembers.add(newMember);
		Collections.sort(this.allMembers, this);
		return true;
	}

	/**
	 * 更新用户列表.
	 * 
	 * @param parser
	 */
	public void clearUpList(JTalkParser parser) {
		// TODO Auto-generated method stub
		boolean userConnected = false;
		for (int i = 0; i < this.allMembers.size(); i++) {
			userConnected = false;
			MemberData member = this.allMembers.get(i);
			for (int j = 0; j < parser.getMemberNum(); j++) {
				if (member.short_name.equals(parser.getAMember(j).name)) {
					if (!member.isConnected()) {
						member.setConnected();
					}
					userConnected = true;
				}
			}
			if (!userConnected) { // 将注销用户从成员列表中移除.
				if (member.isConnected()) {
					member.setDisconnected();
				}
				if (!member.is_connected) {
					this.allMembers.remove(i);
				}
			}
		}

	}

	private boolean saveServerReply(String messageFromServer) {
		// TODO Auto-generated method stub
		return true;
	}

	/** Gets server data */
	public String getServerInfo() {
		return this.serverName + ":" + this.serverPort;
	}

	/**
	 * 设置用户名
	 * 
	 * @param userName
	 *            用户名.
	 */
	public void setUserName(String userName) {
		this.userName = userName;
	}

	@Override
	public int compare(Object o1, Object o2) {
		return -1 * ((MemberData) o1).type.compareToIgnoreCase(((MemberData) o2).type);
	}

	/**
	 * 设置密码.
	 * 
	 * @param password
	 *            密码.
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	public class MemberList implements ListModel {

		private ListDataListener dataListener = null;

		public void propertyChanged() {
			this.dataListener.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED,
					allMembers.size() - 1, 0));
		}

		@Override
		public int getSize() {
			return allMembers.size();
		}

		@Override
		public Object getElementAt(int index) {
			return allMembers.get(index);
		}

		@Override
		public void addListDataListener(ListDataListener l) {
			this.dataListener = l;
		}

		@Override
		public void removeListDataListener(ListDataListener l) {

		}
	}

	/** Inner class with informations about all users and theirs messages */
	public class MemberData {
		public String name = null;
		public String short_name = null;
		public String ip = null;
		public String status = null;
		public String type = null;

		private boolean is_connected = true;
		public boolean hasNewMessage = false;

		private List<Message> messageList = new ArrayList<Message>();
		private JTalkChat chatWindow = null;

		private final static String CONNECT_MESSAGE = "Server: User is ONLINE!";
		private static final String DISCONNECT_MESSAGE = "Server: User is OFFLINE!";

		public MemberData(String name, String ip, String status, String userType) {
			this.name = name + " AT " + ip;
			this.short_name = name;
			this.ip = ip;
			this.status = status;
			this.type = userType == null ? JTalkParser.USER_TYPE_PERSISTENT : userType;
		}

		public void setDisconnected() {
			this.is_connected = false;
			boolean tempState = this.hasNewMessage;
			this.addMessage("<table border=\"0\" width=\"100%\"><tr><td bgcolor=\"#ff0000\">"
					+ MemberData.DISCONNECT_MESSAGE + "</td></tr></table>", "User is offline", "normal");
			if (!this.chatWindowOpened()) {
				this.hasNewMessage = tempState;
			}
		}

		public void setConnected() {
			this.is_connected = true;
			/** Save last state of unread messages */
			boolean tempState = this.hasNewMessage;
			this.addMessage("<table border=\"0\" width=\"100%\"><tr><td bgcolor=\"#00ff00\">"
					+ MemberData.CONNECT_MESSAGE + "</td></tr></table>", "User is online", "normal");
			if (!this.chatWindowOpened()) {
				this.hasNewMessage = tempState;
			}
		}

		public void addMessage(String content, String subject, String type) {
			if (content == null) {
				return;
			}
			this.hasNewMessage = true;
			this.messageList.add(new Message(content, new Date().toString(), subject, type));
			 if (this.chatWindowOpened()) {
			 this.chatWindow.updateWindow();
			 }
		}

		/**
		 * 判断窗口是否打开.
		 * 
		 * @return
		 */
		public boolean chatWindowOpened() {
			boolean isOpened = false;
			if (this.chatWindow != null) {
				isOpened = this.chatWindow.isVisible();
			}
			return isOpened;
		}

		public boolean isConnected() {
			return this.is_connected;
		}

		@Override
		public String toString() {
			return this.short_name + "@" + this.ip;
		}

		/**
		 * 打开聊天窗口.
		 * 
		 * @param jTalkClientFront
		 */
		public void showChatWindow(JTalkClientFront parent) {
			if (this.chatWindow == null) {
				this.chatWindow = new JTalkChat(parent, this);
			}
			this.chatWindow.setVisible(true);
			this.chatWindow.toFront();
			this.chatWindow.updateWindow();
		}

		/**
		 * 获取消息数.
		 * 
		 * @return
		 */
		public int numOfMessages() {
			return this.messageList.size();
		}

		/**
		 * 获取一条消息.
		 * 
		 * @param i
		 * @return
		 */
		public String getMessage(int i) {
			String s = null;
			Message msg = this.messageList.get(i);
			if (msg.type.equals("normal")) {
				s = msg.content;
			}
			return s;
		}

		/**
		 * 客户端人员的消息类.
		 * 
		 * @author Administrator
		 * 
		 */
		public class Message {

			public String content = null;
			public String subject = null;
			public String type = null;
			public String date = null;

			public Message(String content, String date, String subject, String type) {
				// TODO Auto-generated constructor stub
				this.date = date;
				this.content = content;
				this.subject = subject;
				this.type = type == null ? "null" : type;
			}
		}

		public String getDate(int index) {
			return this.messageList.get(index).date;
		}

		/**
		 * 保存文件.此方法会引起线程安全问题.
		 * 
		 * @return
		 */
		public synchronized boolean saveFiles() {
			// TODO Auto-generated method stub
			// System.out.println("--------saveFiles------" + Thread.currentThread());
			for (int i = 0; i < this.messageList.size(); i++) {
				Message m = this.messageList.get(i);
				// System.out.println("--------m.type------" + m.type + "-" + m.content + "-" + Thread.currentThread());
				if ("file".equals(m.type)) {
					Base64Handler handler = new Base64Handler(this.chatWindow);
					if (!handler.saveDecodedData(m.content, m.subject)) {
						System.out.println("Can't decode file: " + handler.getLastError());
					}
					// try {
					// Thread.sleep(1000);
					// } catch (InterruptedException e) {
					// // TODO Auto-generated catch block
					// e.printStackTrace();
					// }
					this.messageList.remove(i);
					// System.out.println("-------this.messageList.remove(i);--------" + this.messageList.size()
					// + "-" + this.messageList.remove(i).content);
					return true;
				}
			}
			return false;
		}

		public void destroyChatWindow() {
			if (this.chatWindow != null) {
				this.chatWindow.dispose();
			}
		}
	}

	/**
	 * 向服务器发送消息.
	 * 
	 * @param message
	 * @return
	 */
	public boolean sendToServer(String message) {
		// TODO Auto-generated method stub
		boolean retValue = false;
		if (this.isConnected && message != null) {
			try {
//				this.thread.setSendText(message);
				this.thread.add(message);
				this.thread.setChannelWritable();
//				socketChannel.register(selector, SelectionKey.OP_WRITE);
//				selector.select();
//				keys = selector.selectedKeys();
//				System.out.println("OP_WRITE:" + keys.size());
//				iterator = keys.iterator();
//				while(iterator.hasNext()){
//					key = iterator.next();
//					iterator.remove();
//					if(key.isWritable()){
//						sendBuffer.clear();
//						sendBuffer.put(message.getBytes());
//						sendBuffer.flip();
//						socketChannel.write(sendBuffer);
//						System.out.println("[send:]" + message);
//						socketChannel.register(selector, SelectionKey.OP_READ);
//					}
//				}
				// this.out.println(message);
				retValue = true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return retValue;
	}

	public SocketChannel getSocketChannel() {
		return socketChannel;
	}

	public void closeConnection() {
		// TODO Auto-generated method stub
		System.out.println(">>> Close connection...");
		this.state = STATE_OFFLINE;
		this.allMembers.clear();
		this.clientThread.terminate();
		this.removeAllConnectionObjects();
		this.memberList.propertyChanged();

		try {
//			this.out.close();
//			this.in.close();
//			this.socket.close();
			this.selector.close();
			this.socketChannel.close();
			this.isConnected = false;
			this.setLastCommandResponse("disconnect01", null, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭所有打开的聊天窗口.
	 */
	private void removeAllConnectionObjects() {
		for (MemberData m : this.allMembers) {
			m.destroyChatWindow();
		}
	}

	public boolean sendMessage(String message, String receiver) {
		// TODO Auto-generated method stub
		System.out.println(">>> Send Message...");
		return this.myProtocal.sendMessage(message, receiver, "normal", null, null);
	}

	/**
	 * 向服务器发送命令.
	 * 
	 * @param message
	 * @param receiver
	 * @param type
	 * @param subject
	 * @param id
	 */
	public boolean sendMessage(String message, String receiver, String type, String subject, String id) {
		System.out.println(">>> Send Message... Type:" + type + " ID:" + id);
		return this.myProtocal.sendMessage(message, receiver, type, subject, id);
	}

	/**
	 * 注册命令执行者.
	 * 
	 * @param jTalkChatRoomCreater
	 */
	public void registerForCommandResponse(JTalkClientCommandInterface command) {
		for (JTalkClientCommandInterface c : commands) {
			if (c == command) {
				System.out.println("*** registerForCommandResponse: Object has been already registered: "
						+ command.toString());
				return;
			}
		}
		commands.add(command);
	}

	/**
	 * 执行命令响应方法.
	 * 
	 * @param messageID
	 * @param sender
	 * @param content
	 */
	public void setLastCommandResponse(String messageID, String sender, String content) {
		this.lastCommandResponse = content;
		for (JTalkClientCommandInterface c : commands) {
			c.setCommandAnswer(messageID, sender, content);
		}
	}

	/**
	 * 发送消息,发送文件时有调用.
	 * 
	 * @param message
	 * @param receiver
	 * @param type
	 * @param subject
	 * @return
	 */
	public boolean sendMessage(String message, String receiver, String type, String subject) {
		System.out.println(">>> Send Message... Type:" + type);
		return this.myProtocal.sendMessage(message, receiver, type, subject, null);
	}

	/**
	 * 切换用户状态时发送的消息.
	 */
	public boolean lookUp() {
		// TODO Auto-generated method stub
		System.out.println(">>> Lookup for Messages...");
		return this.myProtocal.sendUserStatus(false);
	}

	/**
	 * 保存设置.
	 */
	public boolean saveSettings() {
		try {
			File myconfig = new File(this.configFile);
			FileWriter writer = new FileWriter(myconfig);
			String tmpConfig = "<" + JTalkParser.CONFIG_ROOT + ">" + "\n  <" + JTalkParser.CONFIG_SERVER + " "
					+ JTalkParser.CONFIG_SERVER_IP + "=\"" + this.serverName + "\"" + " "
					+ JTalkParser.CONFIG_SERVER_SSL + "=\"" + this.useSSL + "\"" + " " + JTalkParser.CONFIG_SERVER_PORT
					+ "=\"" + this.serverPort + "\" />" + "\n  <" + JTalkParser.CONFIG_ACCOUNT + " "
					+ JTalkParser.CONFIG_ACCOUNT_NAME + "=\"" + this.userName + "\"";
			if (this.savePassword) {
				tmpConfig += " " + JTalkParser.CONFIG_ACCOUNT_PASSWD + "=\"" + this.password + "\" />";
			} else {
				tmpConfig += " />";
			}
			tmpConfig += ("\n  <" + JTalkParser.CONFIG_APPS + " " + JTalkParser.CONFIG_APPS_BROWSER + "=\""
					+ this.defaultBrowser + "\"" + " " + JTalkParser.CONFIG_APPS_MAIL + "=\"" + this.defaultMailer
					+ "\" />" + "\n  <" + JTalkParser.CONFIG_LOOK + " " + JTalkParser.CONFIG_LOOK_PLAF + "=\""
					+ this.guiPlaf + "\"" + " " + JTalkParser.CONFIG_LOOK_TEXTCOLOR + "=\"" + this.guiTextColor + "\""
					+ " " + JTalkParser.CONFIG_LOOK_BGCOLOR + "=\"" + this.guiBgColor + "\" />" + "\n  <"
					+ JTalkParser.CONFIG_NOTIFICATION + " " + JTalkParser.CONFIG_NOTIFICATION_USERLIST + "=\""
					+ this.newMailNotificationType + "\" />" + "\n  <" + JTalkParser.CONFIG_PLUGINS + " "
					+ JTalkParser.CONFIG_PLUGINS_DIR + "=\"" + this.pluginDir + "\"" + " "
					+ JTalkParser.CONFIG_PLUGINS_SHORTCUT + "=\"" + this.pluginShortcuts + "\" />" + "\n</"
					+ JTalkParser.CONFIG_ROOT + ">");
			writer.write(tmpConfig);
			writer.close();
			return true;
		} catch (IOException e) {
			System.err.println("*** ERROR: " + e.toString());
			return false;
		}

	}

	/**
	 * 在工具栏中添加插件快捷方式.
	 * 
	 * @param plugin
	 */
	public boolean addPluginShortcut(String plugin) {
		if (!this.isPluginShortcut(plugin)) {
			this.pluginShortcuts += plugin + ",";
			return true;
		}
		return false;
	}

	/**
	 * 校验插件名是否已经存在.
	 * 
	 * @param plugin
	 *            插件名称.
	 * @return
	 */
	private boolean isPluginShortcut(String plugin) {
		String[] embededPlugins = this.pluginShortcuts.split(",");
		for (String s : embededPlugins) {
			if (plugin.equals(s)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 删除插件的快捷方式.
	 * 
	 * @param plugin
	 *            插件名称.
	 * @return
	 */
	public boolean removePluginShortcut(String plugin) {
		String[] embededPlugins = this.pluginShortcuts.split(",");
		this.pluginShortcuts = "";
		boolean retVal = false;
		for (String s : embededPlugins) {
			if (!s.equals(plugin)) {
				this.addPluginShortcut(s);
				retVal = false;
			}
		}
		return retVal;
	}

	/**
	 * 获取插件的快捷方式.
	 * 
	 * @return
	 */
	public String[] getPluginShortcuts() {
		String[] shortCuts = this.pluginShortcuts.split(",");
		return shortCuts;
	}

	/**
	 * 设置客户端显示面板.
	 * 
	 * @param jTalkClientFront
	 */
	public void setFrontend(JTalkClientFront jTalkClientFront) {
		this.myFrontend = jTalkClientFront;
	}

	/**
	 * 获取客户端显示面板.
	 * 
	 * @return
	 */
	public JTalkClientFront getFrontend() {
		return this.myFrontend;
	}

	/**
	 * 注销命令.
	 * 
	 * @param command
	 */
	public void deRegisterForCommandResponse(JTalkClientCommandInterface command) {
		if (this.commands.remove(command)) {
			System.out.println("*** deRegisterForCommandResponse: object removed: " + command.getClass().getName());
		}
	}

	/**
	 * 根据成员名字获取成员.
	 * 
	 * @param name
	 * @return
	 */
	public MemberData getMemberByName(String name) {
		for (MemberData m : this.allMembers) {
			if (m.name.equals(name)) {
				return m;
			}
		}
		return null;
	}
}
